import json
import datetime
import re


class DateEncoder(json.JSONEncoder):
    """json 针对时间对象的序列器"""

    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        elif isinstance(obj, datetime.date):
            return obj.strftime("%Y-%m-%d")
        elif type(obj) not in [int, float, list, tuple, dict, set, str, bytes]:
            if hasattr(obj, 'to_dict'):
                return obj.to_dict()

        return json.JSONEncoder.default(self, obj)


def merge_dict(source_dict: dict, target_dict: dict):
    """合并两个字典数据，返回一个新字典"""
    ret = {}
    for k, v in source_dict.items():
        ret[k] = v

    for k, v in target_dict.items():
        ret[k] = v
    return ret


def set_db_ins_value(instance, fields, data: dict):
    """更新数据表实例的值"""
    update_fields = []
    for key, value in data.items():
        if key in fields:
            update_fields.append(key)
            setattr(instance, key, value)

    if update_fields:
        instance.save(update_fields=update_fields)


def get_model_fields(model_class, exclude_fields=None):
    """获取django 模型的字段列表"""
    if exclude_fields is None:
        exclude_fields = []

    data = []
    for field in model_class._meta.fields:
        field_name = field.name
        if field_name in exclude_fields:
            continue

        if field.primary_key or field.many_to_many or field.many_to_one or field.one_to_many:
            continue

        data.append(field_name)

    return data


def copy_data_from_other(source_data, target_model, exclude_fields=None):
    """获取数据库实例的字段值"""
    if exclude_fields is None:
        exclude_fields = []

    data = {}
    for field in target_model._meta.fields:
        field_name = field.name
        if field_name in exclude_fields:
            continue

        if field.primary_key or field.many_to_many or field.many_to_one or field.one_to_many:
            continue

        if field_name in source_data:
            data[field_name] = source_data[field_name]

    return data


def get_account_from_username(username: str):
    """从用户名中获取域账号"""
    if '(' in username:
        g = re.findall(r"\(([a-zA-Z0-9_-]+)\)", username)
        if g:
            return g[0]

    return username
